package com.des1gn.ymgetil.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.des1gn.ymgetil.model.*;
import com.des1gn.ymgetil.service.*;
import com.des1gn.ymgetil.thread.ExecutorPool;
import com.des1gn.ymgetil.util.SnowFlakeUtil;
import com.des1gn.ymgetil.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.net.Proxy;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;

/**
 * @ClassName TaskServiceImpl
 * @Description TODO
 * @Author Des1gn
 * @Date 2021/11/25 9:49
 * @Version 1.0
 **/
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    private static int totalNum = 10;

    private static int currentNum = 1;

    private static final Map<String,TaskModel> taskMap = new HashMap<>();

    private static final SnowFlakeUtil snwflak = new SnowFlakeUtil(1,1);

    @Autowired
    SmallTypeService smallTypeService;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    MiaoService miaoService;


    @Override
    public TaskModel addTask(TaskModel taskModel) {
        String id = String.valueOf(snwflak.nextId());
        taskMap.put(id,taskModel);
        new Thread(()->{
            long startTime = DateUtil.parseDateTime(taskModel.getTaskStartTime()).getTime();
            long nowTime = System.currentTimeMillis();
            try {
                Thread.sleep(startTime-nowTime-500);
                doTask(taskModel,id);
                Thread.sleep(100);
                doTask(taskModel,id);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
        return taskModel;
    }

    @Override
    public void removeTask(String id) {
        for (String key : taskMap.keySet()){
            if (key.equals(id)){
                taskMap.remove(id);
                return;
            }
        }
    }

    @Override
    public List<TaskModel> queryTask(String dateTime) {
        List<TaskModel> result = new LinkedList<>();
        for (TaskModel taskModel : taskMap.values()){
            if (taskModel.getTaskStartTime().equals(dateTime) && StringUtils.isEmpty(taskModel.getOrderStatus())){
                result.add(taskModel);
            }
        }
        return result;
    }

    @Override
    public List<TaskModelVo> getTaskList() {
        List<TaskModelVo> result = new LinkedList<>();
        for (String key : taskMap.keySet()){
            TaskModelVo taskModelVo = new TaskModelVo();
            taskModelVo.setId(key);
            BeanUtils.copyProperties(taskMap.get(key),taskModelVo);
            result.add(taskModelVo);
        }
        return result;
    }

    @Override
    public void setNewSessionId(String oldSessionId, String newSessionId) {
        if (taskMap.containsKey(oldSessionId)){
            TaskModel taskModel = taskMap.get(oldSessionId);
            taskModel.setSessionId(newSessionId);
            taskMap.remove(oldSessionId);
            taskMap.put(newSessionId,taskModel);
        }
    }

    @Override
    public void syncOrderStatus() {
        for (String key : taskMap.keySet()){
            TaskModel taskModel = taskMap.get(key);
            List<OrderInfo> orderList = smallTypeService.getOrderList(taskModel.getSessionId());
            if (!CollectionUtils.isEmpty(orderList) && !orderList.get(0).getIsCancel() && !orderList.get(0).getIsFinished()){
                taskModel.setOrderStatus("SUCCESS");
                taskMap.put(key, taskModel);
            }
//            JSONObject no = new JSONObject();
//            no.put("cookie",key);
//            int num = 0;
//            do{
//                num++;
//                if (no.containsKey("cookie") && !StringUtils.isEmpty(no.getString("cookie"))) {
//                    no = smallTypeService.getOrderStatus(no.getString("cookie"));
//                }else {
//                    no = smallTypeService.getOrderStatus(key);
//                }
//            }while (no.containsKey("Fnumber") && StringUtils.isEmpty(no.getString("Fnumber"))  && !no.getString("msg").equals("该身份证或微信号已有预约信息.") && num<3);
//            if (StringUtils.isEmpty(no.getString("Fnumber")) && !no.getString("msg").equals("该身份证或微信号已有预约信息.")){
//                continue;
//            }else {
//                taskModel.setOrderStatus(no.getString("Fnumber"));
//                taskMap.put(taskModel.getSessionId(), taskModel);
//            }
        }
    }

    @Override
    public void doTask(TaskModel taskModel,String id) {
        for (int i = 0; i < totalNum; i++) {
            ExecutorPool.submit(()->createThread(taskModel,id));
        }
    }

    @Override
    public void doMiaoTask(MiaoSubmitDto miaoSubmitDto) {
        new Thread(()->{
            long startTime = DateUtil.parseDateTime(miaoSubmitDto.getSubmitTime()).getTime();
            long nowTime = System.currentTimeMillis();
            try {
                Thread.sleep(startTime-nowTime-1000);
                doMiaoTaskProcessor(miaoSubmitDto);
                Thread.sleep(startTime-nowTime-300);
                doMiaoTaskProcessor(miaoSubmitDto);
                Thread.sleep(startTime-nowTime-50);
                doMiaoTaskProcessor(miaoSubmitDto);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
    }

    private void doMiaoTaskProcessor(MiaoSubmitDto miaoSubmitDto){
        for (int i = 0;i<totalNum;i++){
            ExecutorPool.submit(()->{
                try {
                    String orderId = miaoService.submitOrder(miaoSubmitDto.getTk(), miaoSubmitDto.getMsId(), miaoSubmitDto.getUserId(), miaoSubmitDto.getIdCardNo());
                    if (!StringUtils.isEmpty(orderId)){
                        List<String> dates = miaoService.getDates(miaoSubmitDto.getTk(), miaoSubmitDto.getMsId(), orderId);
                        for (String day : dates){
                            List<String> times = miaoService.getTimes(miaoSubmitDto.getTk(), miaoSubmitDto.getMsId(), orderId, day);
                            for (String time : times){
                                Boolean isSuccess = miaoService.toSubmit(miaoSubmitDto.getTk(), miaoSubmitDto.getMsId(), orderId, day, time);
                                if (isSuccess){
                                    log.warn("订单预约成功-----------SUCCESS");
                                    System.out.println("订单预约成功");
                                    return;
                                }
                            }
                        }
                        log.warn("订单提交成功-----------SUCCESS");
                    }
                }catch (Exception e){
                    log.error("提交订单失败{}",e);
                }
            });
        }
    }

    private void createThread(TaskModel taskModel,String id){
        try {
            String sessionId = taskModel.getSessionId();
            String productId = taskModel.getProductId();
            String hospitalId = taskModel.getHospitalId();
            UserInfoModel userInfo = userInfoService.getUserInfo(sessionId);
            List<DateDetail> dateDetails = smallTypeService.getDateDetails(sessionId, productId, hospitalId, DateTime.now().toString("yyyy-MM"));
            for (DateDetail dateDetail : dateDetails) {
                String dateStr = dateDetail.getDate();
                TaskModel thisTask = taskMap.get(id);
                if (!StringUtils.isEmpty(thisTask.getOrderStatus()) && thisTask.equals("SUCCESS")){
                    return;
                }
                List<TimeDetail> timeDetails = smallTypeService.getTimeDetails(sessionId, productId, hospitalId, dateStr,userInfo.getKey());
                if (CollectionUtils.isEmpty(timeDetails)){
                    continue;
                }
                for (TimeDetail timeDetail : timeDetails){
                    if (timeDetail.getQty() > 0){
                        String captchaCookie = smallTypeService.getCaptcha(sessionId, timeDetail.getMxid());
                        if (!StringUtils.isEmpty(captchaCookie)) {
                            String submitCookie = smallTypeService.submitOrder(captchaCookie, timeDetail.getMxid(), productId, dateStr, userInfo);
                            if (!StringUtils.isEmpty(submitCookie)){
                                String name = userInfoService.getUserInfo(taskModel.getSessionId()).getCname();
                                log.warn("提交成功 SUCCESSFUL 本次成功是: {}································",name);
                                return;
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("任务执行错误.{}",e);
        }
    }
}
